package xfuzzy.xfhl.model.spec;


import xfuzzy.lang.BinaryRelation;
import xfuzzy.lang.Conclusion;
import xfuzzy.lang.KnowledgeBase;
import xfuzzy.lang.LinguisticLabel;
import xfuzzy.lang.Operatorset;
import xfuzzy.lang.Relation;
import xfuzzy.lang.Rule;
import xfuzzy.lang.RuleSet;
import xfuzzy.lang.SingleRelation;
import xfuzzy.lang.Variable;

/**
 * Clase que nos crea un conjunto de reglas (RuleSet)
 * 
 * @author Sergio Cala Cordero, Septiembre 2009, Herramienta XFHL
 *
 */
public class XfhlRuleSet {
	
	
	/**
	 * M�todo est�tico que crea un RuleSet
	 * @param name     Nombre del conjuto de reglas
	 * @param varIn1   Variable de entrada 1
	 * @param varIn2   Variable de entrada 2
	 * @param varOut   Variable de salida
	 * @param operSet  Conjunto de operadores que usar� el Conjuto de reglas
	 * @return    el RuleSet creado
	 */
	public static RuleSet create(String name,Variable varIn1, Variable varIn2,Variable varOut, Operatorset operSet)
	{
		//Creamos la base de reglas
	    RuleSet ruleSet=new RuleSet(name);
	    	    
	    //Variables de entrada	 
	    ruleSet.addInputVariable(varIn1);
	    ruleSet.addInputVariable(varIn2);
	    
	    //Variable de salida
	    ruleSet.addOutputVariable(varOut);
	    
	    //Asignamos el conjunto de operadores
	    ruleSet.setOperatorset(operSet);	    
	    	       	   
	    
	    int i=0;
	    for (LinguisticLabel lIn1 : varIn1.getType().getMembershipFunctions()) {
	    	for (LinguisticLabel lIn2 : varIn2.getType().getMembershipFunctions()) {		
	    		//Creamos las reglas
	    		Rule r=createRule(varIn1, lIn1, varIn2, lIn2, varOut, varOut.getType().getMembershipFunctions()[i], ruleSet);
	    		i++;
	    		ruleSet.addRule(r);
	    	}
		}
	    
	    return ruleSet;
	}
	
	
	/**
	 * Metodo est�tico que crea una regla. Dos entradas una salida.
	 * @param vIn1   Variable de entrada 1
	 * @param lIn1   Etiqueta Linguistica de entrada 1
	 * @param vIn2   Variable de entrada 2
	 * @param lIn2   Etiqueta Linguistica de entrada 2
	 * @param vOut   Variable de salida
	 * @param lOut   Etiqueta Linguistica de salida
	 * @param kBase  Base de reglas a la que pertence la regla
	 * @return       el Rule creado
	 */
    private static Rule createRule(Variable vIn1,LinguisticLabel lIn1, Variable vIn2,LinguisticLabel lIn2,Variable vOut,LinguisticLabel lOut,KnowledgeBase kBase)
	{
		Rule r;
		//Premisa		
		SingleRelation sr1=new SingleRelation(Relation.IS,vIn1,lIn1,kBase);
		SingleRelation sr2=new SingleRelation(Relation.IS,vIn2,lIn2,kBase);
		BinaryRelation premisa=new BinaryRelation(Relation.AND,sr1,sr2,kBase);		
		//Conclusion
		Conclusion c=new Conclusion(vOut,lOut,kBase);

		//Creamos la regla
		r=new Rule(premisa);
		r.add(c);
		return r;
	}
	
	
}
